package permission

import (
	"context"
	"errors"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"private-domain-overseas-service/admin/business/api/internal/repository/permission"
	"private-domain-overseas-service/admin/business/api/internal/svc"
	"private-domain-overseas-service/admin/business/api/internal/types"
	"private-domain-overseas-service/pkg/common"
	"private-domain-overseas-service/pkg/status/bizadmin"
	"private-domain-overseas-service/pkg/xerr"
	"private-domain-overseas-service/tools/ent"
	"private-domain-overseas-service/tools/ent/adminuser"
	"private-domain-overseas-service/tools/ent/adminuserrole"
	"private-domain-overseas-service/tools/ent/predicate"
)

type AdminUserEditLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewAdminUserEditLogic - 后台用户编辑接口
func NewAdminUserEditLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminUserEditLogic {
	return &AdminUserEditLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AdminUserEditLogic) AdminUserEdit(req *types.AdminUserEditRequest) error {
	adminUserDAO := permission.NewAdminUserDao(l.ctx, l.svcCtx)
	adminUserRoleDAO := permission.NewAdminUserRoleDao(l.ctx, l.svcCtx)

	userId := common.JwtAuthUserId(l.ctx)

	err := common.WithTx(l.ctx, l.svcCtx.Orm, func(tx *ent.Tx) error {
		// 新增
		if req.OperateType == bizadmin.TypeAdd {
			// 查询用户
			adminUserConditions := make([]predicate.AdminUser, 0, 1)
			adminUserConditions = append(adminUserConditions, adminuser.AdminUserUsernameEQ(req.AdminUserUserName))
			user, err := adminUserDAO.AdminUserFirst(adminUserConditions)
			if user != nil {
				return err
			}
			if err != nil && !ent.IsNotFound(err) {
				return err
			}

			// 加密密码
			hashPwd, err := common.HashPassword(req.AdminUserPassword)
			if err != nil {
				return errors.New(fmt.Sprintf("加密密码错误:%v", err.Error()))
			}
			req.AdminUserPassword = hashPwd

			// 创建用户
			request := ent.AdminUser{
				AdminUserUsername: req.AdminUserUserName,
				AdminUserNickname: req.AdminUserNickname,
				AdminUserEmail:    req.AdminUserEmail,
				AdminUserPassword: req.AdminUserPassword,
				AdminUserStatus:   req.AdminUserStatus,
			}
			adminUser, err := adminUserDAO.AdminUserCreate(&request, tx)
			if err != nil {
				return errors.New(fmt.Sprintf("创建用户失败: %v", err.Error()))
			}

			// 根据新传入的角色id，批量添加用户角色关联
			err = adminUserRoleDAO.AdminUserRoleBatchCreate(int64(adminUser.ID), req.AdminUserRoleId, tx)
			if err != nil {
				return errors.New(fmt.Sprintf("批量添加用户角色关联失败: %v", err.Error()))
			}
		}

		// 更新
		if req.OperateType == bizadmin.TypeEdit {
			if req.ID == userId && req.AdminUserStatus == bizadmin.StatusDisable {
				return errors.New("不能禁用自己")
			}

			// 判断id是否为空
			if req.ID == 0 {
				return errors.New("id为0")
			}

			// 如果更新密码，则重新加密
			if req.AdminUserPassword != "" {
				// 根据id查询用户
				adminUserConditions := make([]predicate.AdminUser, 0, 2)
				adminUserConditions = append(adminUserConditions, adminuser.IDEQ(int(req.ID)))
				adminUserConditions = append(adminUserConditions, adminuser.IsDelete(bizadmin.NotDelete))
				adminUser, err := adminUserDAO.AdminUserFirst(adminUserConditions)
				if err != nil {
					return errors.New(fmt.Sprintf("查不到id对应用户: %v", err.Error()))
				}

				// 传入的与原有的密码不一致，则重新加密
				if adminUser.AdminUserPassword != req.AdminUserPassword {
					hashPwd, err := common.HashPassword(req.AdminUserPassword)
					if err != nil {
						return errors.New(fmt.Sprintf("加密密码错误: %v", err.Error()))
					}
					req.AdminUserPassword = hashPwd
				}
			}

			// 组装数据
			request := ent.AdminUser{
				ID:                int(req.ID),
				AdminUserUsername: req.AdminUserUserName,
				AdminUserPassword: req.AdminUserPassword,
				AdminUserStatus:   req.AdminUserStatus,
				AdminUserNickname: req.AdminUserNickname,
				AdminUserEmail:    req.AdminUserEmail,
				IsDelete:          bizadmin.NotDelete,
			}
			// 更新用户信息
			err := adminUserDAO.AdminUserUpdate(&request, tx)
			if err != nil {
				return errors.New(fmt.Sprintf("更新用户信息失败: %v", err.Error()))
			}

			// 更新用户角色关联
			// 清除原来用户角色关联
			adminUserRoleCond := make([]predicate.AdminUserRole, 0, 1)
			adminUserRoleCond = append(adminUserRoleCond, adminuserrole.AdminUserRoleUserIDEQ(req.ID))
			err = adminUserRoleDAO.AdminUserRoleDelete(adminUserRoleCond)
			if err != nil {
				return errors.New(fmt.Sprintf("删除用户角色关联失败: %v", err.Error()))
			}

			// 根据新传入的角色id，批量添加用户角色关联
			err = adminUserRoleDAO.AdminUserRoleBatchCreate(req.ID, req.AdminUserRoleId, tx)
			if err != nil {
				return errors.New(fmt.Sprintf("批量添加用户角色关联失败: %v", err.Error()))
			}
		}
		return nil
	})
	if err != nil {
		return xerr.ErrCodeMsg(xerr.ServerOperationExceptionError, err.Error())
	}

	return nil
}
